import processing.serial.*;

//Constants
int NUM_INPUTS = 6; //number of analog inputs
int URL_UPDATE_RATE = 50; //period between updates in milliseconds
int SERIAL_UPDATE_RATE = 10; //period between updates in milliseconds
int MAX_X = 512; //window size x
int MAX_Y = 256; //window size y

//Arduino
int ANALOGVAL_MAX = 1024; //maximum analog value
int[] analogValue = new int[NUM_INPUTS];
int[] analogValueOld = new int[NUM_INPUTS];
int[] switchState = new int[NUM_INPUTS];
int[] switchStateOld = new int[NUM_INPUTS];

//web
String url_catcher = "http://localhost/arduino/www/php_catcher.php";
boolean postWorked = false;

//Serial
Serial port;

// buffer and value variable for each value and boolean to switch between values
boolean firstContact = false;
int serialCount = 0;
int[] serialInArray = new int[NUM_INPUTS*2];
int[] serialValue = new int[NUM_INPUTS];

//Drawing

int NUM_COLUMNS = 6;
int NUM_ROWS = 4;
int columnWidth = MAX_X / NUM_COLUMNS;
int rowHeight = MAX_Y / NUM_ROWS;

color off = color(200,200,255);
color on = color(84, 145, 158);
PFont fontA;

//General
int i, j, k;

void setup() {

size(MAX_X, MAX_Y);
// Set the font and its size (in units of pixels)
fontA = loadFont("LucidaSans-16.vlw");
textFont(fontA, 16);

initializeSerial(1, 9600);
initializeVars();
}

void draw() {

//PROCESS THE LATEST SERIAL INPUT
processInput();

//SEND TO URL IF URL TIMER HAS TICKED OVER
if (timer_URLupdate(URL_UPDATE_RATE)) postToURL();

//UPDATE THE DISPLAY
updateDisplay();

//IF NO SERIAL CONTACT HAS BEEN MADE
if (firstContact == false) {
delay(300);
port.write(65);
} else {
//GRAB SERIAL DATA IF SERIAL TIMER HAS TICKED OVER
if ((serialCount==0)&&(timer_Serial(SERIAL_UPDATE_RATE))) port.write(65);
}

delay(10);
}

void initializeVars()
{
for (int i = 0; i < NUM_INPUTS; i++)
{
analogValue[i] = 0;
analogValueOld[i] = -1;
switchState[i] = 1;
switchStateOld[i] = -1;
//postParams[i] = "switch" + Integer.toString(i);
//postValues[i] = "-1";
}
}

//To Get the on/off value from the analog input which is sent to the text file the webpage reads from on the server
void processInput()
{
for (int i = 0; i < NUM_INPUTS; i++) {
if (analogValue[i] < 500)
switchState[i] = 0;
else
switchState[i] = 1;
}
}

//Graphical interface update, to show if processing is picking up the analog input in a nice pretty fashion.
void updateDisplay()
{
background(off);
stroke(on);
text("val" , 2, rowHeight * 2 + (rowHeight/2));


for (int i = 0; i < NUM_INPUTS; i++)
{
stroke(255);
fill(255);
//Draw circles representing analog value
ellipse(i*columnWidth+columnWidth/2, rowHeight/2,
analogValue[i] / (ANALOGVAL_MAX / rowHeight),analogValue[i] / (ANALOGVAL_MAX / rowHeight));

//Draw dots representing ON/OFF state
if (switchState[i] == 1)
ellipse(i*columnWidth+columnWidth/2, rowHeight+rowHeight/2, rowHeight/4, rowHeight/4);

//Print values data
stroke(0,0,0);
fill(0,0,0);
text(analogValue[i], i * columnWidth + columnWidth/3, rowHeight * 2 + (rowHeight/2));
text(switchState[i], i * columnWidth + columnWidth/3, rowHeight * 3 + (rowHeight/2));
}
}

//post_id array protocol
// {PARAM_ID1, NUM_OF_VALUES, VALUE1, VALUE2, ..., PARAM_ID1, NUM_VALUES, VALUE1, VALUE2, ...}

String P_ID_STATES = "100";
String P_ID_ANALOG = "101";
//int PARAM_ID_ANALOG_VALUES = 101;

String[] postParams = {"P_ID_1", "P_ID_STATES","P_ID_2","P_ID_ANALOG"};
String[] postValues = new String[4];

void postToURL()
{
postValues[0] = P_ID_STATES;
postValues[1] = join(nf(switchState,1),"'");
postValues[2] = P_ID_ANALOG;
postValues[3] = join(nf(analogValue,4),"'");
postWorked = postNewItem(postParams,postValues, url_catcher);
}

int timerPrevURL = 0;
boolean timer_URLupdate(int timerPeriod)
{
boolean ret = false;
int timer = millis();
if ((timer - timerPrevURL) > timerPeriod)
{
ret = true;
timerPrevURL = timer;
}
return ret;
}

int timerPrevSerial = 0;
boolean timer_Serial(int timerPeriod)
{
boolean ret = false;
int timer = millis();
if ((timer - timerPrevSerial) > timerPeriod)
{
ret = true;
timerPrevSerial = timer;
}
return ret;
}

void initializeSerial(int portNum, int baudrate)
{
// establish serial port connection
// port = new Serial(this, portname, baudrate);
println("Available serial ports:");
println(Serial.list());

// Uses the first available port
port = new Serial(this, Serial.list()[portNum], baudrate);
println(port);
port.write(65);
}

void serialEvent(Serial port) {
// if this is the first byte received,
// take note of that fact:
if (firstContact == false) {
firstContact = true;
}
// Add the latest byte from the serial port to array:
serialInArray[serialCount] = port.read();
serialCount++;

// If we have 12 bytes:
if (serialCount > 11 ) {
for (i=0;i<6;i++) {
serialValue[i] = serialInArray[i*2];
serialValue[i] <<= 8;
serialValue[i] = serialValue[i] + serialInArray[i*2 + 1];
analogValue[i] = 1023 - serialValue[i];
}
// Reset serialCount:
serialCount = 0;
}
}
boolean postNewItem (String[] Par, String[] Val, String strURL) {
boolean ret = false;
try {
URL url;
URLConnection urlConn;
DataOutputStream dos;
DataInputStream dis;
String s = "";
String S = "";
String query = "";


// generate the query-string (for multiple parameters)
for(int i = 0; i < Par.length; i++){
if(i == 0){
query += "?nump="+Par.length+"&";
}else{
query += "&";
}
query += "p"+(i+1)+"="+Par[i];
}

url = new URL(strURL + query);
urlConn = url.openConnection();
urlConn.setDoInput(true);
urlConn.setDoOutput(true);
urlConn.setUseCaches(false);
urlConn.setRequestProperty ("Content-Type", "application/x-www-form-urlencoded");

dos = new DataOutputStream (urlConn.getOutputStream());

// generate the post-string
for (int i=0; i<Par.length; i++)
{
if (S.length() > 0) S += "&";
S += Par[i] + "=" + Val[i];
}

// SEND
String message=S;
dos.writeBytes(message);
dos.flush();
dos.close();

//println(strURL + query);
//println(message);
// RECIEVE
dis = new DataInputStream(urlConn.getInputStream());
s = dis.readLine();
dis.close();

println(s); // if it outputs success, and nothing happens check this out..
if (s != "") { // Got Some reply
ret = true;
} else {
ret = false;
}

} // end of "try"

catch (MalformedURLException mue) {
;
}
catch (IOException ioe) {
;
}
return ret;
} // end of postNewItem() method 